package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.Video;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.FocusUserService;
import com.itheima.service.mongo.VideoService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.DateFormatUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.VideoVo;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class VideoManager {

    @Reference
    private VideoService videoService;
    @Reference
    private UserInfoService userInfoService;
    @Reference
    private FocusUserService focusUserService;
    @Reference
    private CommentService commentService;


    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private FastFileStorageClient client;
    @Autowired
    private FdfsWebServer webServer;
    @Autowired
    private MQVideoManager mqVideoManager;

    //查询推荐视频
    @Cacheable(value = "video", key = "#userId+'_'+#pageNum+'_'+#pageSize")
    public PageBeanVo findVideo(Long userId, Integer pageNum, Integer pageSize) {
        System.out.println("查询推荐视频");

        //2.调用service根据用户id分页查询视频列表
        PageBeanVo pageBeanVo = videoService.findVideo(userId, pageNum, pageSize);

        //3.处理返回结果
        List<Video> videoList = (List<Video>) pageBeanVo.getItems();
        List<VideoVo> videoVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(videoList)) {
            for (Video video : videoList) {
                //3-1 创建videoVo
                VideoVo videoVo = new VideoVo();
                //3-2 查询该视频的用户信息
                UserInfo userInfo = userInfoService.findByUserId(video.getUserId());
                //3-3封装数据
                BeanUtil.copyProperties(userInfo, videoVo);

                BeanUtil.copyProperties(video, videoVo);
                videoVo.setCover(video.getPicUrl());//设置封面图片
                videoVo.setSignature(video.getText());//设置文案
                videoVo.setHasLiked(1);//todo  实战修改
                String key = StrUtil.format(ConstantUtil.FOCUS_USER, userId, video.getUserId());
                if (stringRedisTemplate.hasKey(key)) {
                    videoVo.setHasFocus(1);//已关注
                } else {
                    videoVo.setHasFocus(0);//未关注
                }
                //3-4  收集
                videoVoList.add(videoVo);
            }

        }
        pageBeanVo.setItems(videoVoList);
        return pageBeanVo;
    }

    //上传视频
    @CacheEvict(value = "video", key = "#userId+'_*'")
    public void saveVideo(Long userId, MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //1.封面上传阿里云
        String picUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        System.out.println("getOriginalFilename：" + videoThumbnail.getOriginalFilename());
        System.out.println("封面的路径" + picUrl);

        //2.视频上传fastdfs,并获取访问地址
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), FileUtil.extName(videoFile.getOriginalFilename()), null);
        System.out.println("视频的大小:" + videoFile.getSize());
        System.out.println("视频的路径:" + videoFile.getOriginalFilename());
        System.out.println("视频的后缀:" + FileUtil.extName(videoFile.getOriginalFilename()));

        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();
        System.out.println("videoUrl:" + webServer.getWebServerUrl() + storePath.getFullPath());

        //3.封装一个video对象
        Video video = new Video();
        video.setCreated(System.currentTimeMillis());
        video.setUserId(UserHolder.get().getId());
        video.setText("女儿情");
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);

        //4. 调用service保存
        videoService.saveVideo(video);

        //5.向MQ发送消息(上传视频)
        mqVideoManager.sendVideoMsg(video.getId().toHexString(), MQVideoManager.VIDEO_PUBLISH);
    }

    //添加关注
    public void saveUserFocus(Long focusUserId) {
        //1. 获取登录用户id
        Long userId = UserHolder.get().getId();

        //2. 组装FocusUser对象
        FocusUser focusUser = new FocusUser();
        focusUser.setUserId(userId);
        focusUser.setFocusUserId(focusUserId);
        focusUser.setCreated(System.currentTimeMillis());

        //3. 将关注标识保存到redis中
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, userId, focusUserId);
        stringRedisTemplate.opsForValue().set(key, "1");

        //4. 调用service保存
        focusUserService.save(focusUser);
    }

    //删除关注
    public void deleteUserFocus(Long focusUserId) {
        //1. 获取登录用户id
        Long userId = UserHolder.get().getId();

        //2. 组装FocusUser对象
        FocusUser focusUser = new FocusUser();
        focusUser.setUserId(userId);
        focusUser.setFocusUserId(focusUserId);

        //3. 将关注标识从到redis中移除
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, userId, focusUserId);
        stringRedisTemplate.delete(key);

        //4. 调用service保存
        focusUserService.delete(focusUser);
    }

    //视频点赞
    public void saveVideoLike(String videoId) {
        Long userId = UserHolder.get().getId();
        //组装评论对象
        Comment comment = new Comment();
        comment.setCommentType(4);
        comment.setPublishId(new ObjectId(videoId));
        comment.setUserId(userId);
        //调用service查询点赞数
        Integer count=commentService.saveVideoComment(comment);
        //将点赞标识放入redis
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE,userId,videoId),"1");

    }

    //视频取消点赞
    public void deleteVideoComment(String videoId) {
        Long userId = UserHolder.get().getId();
        //组装评论对象
        Comment comment = new Comment();
        comment.setCommentType(4);
        comment.setUserId(userId);
        comment.setPublishId(new ObjectId(videoId));

        //调用service
        Integer count=commentService.deleteVideoComment(comment);
        //将点赞标识从入redis删除
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE,userId,videoId));

    }

    //视频评论列表
    public PageBeanVo videoCommentList(String videoId,Integer pageNum,Integer pageSize) {
        Long userId = UserHolder.get().getId();
        PageBeanVo pageBeanVo=videoService.videoCommentList(userId,videoId,pageNum,pageSize);
        List<Comment> videoCommentList = (List<Comment>) pageBeanVo.getItems();


       List<CommentVo> commentVoList = new ArrayList<>();
        //判断遍历
        if (CollectionUtil.isNotEmpty(videoCommentList)) {
            for (Comment comment : videoCommentList) {
                CommentVo commentVo = new CommentVo();
                //设置用户信息
                UserInfo userInfo = userInfoService.findByUserId(comment.getUserId());
                commentVo.setAvatar(userInfo.getAvatar());
                commentVo.setNickname(userInfo.getNickname());

                //设置评论信息
                commentVo.setId(comment.getId().toHexString());
                commentVo.setContent(comment.getContent());
                commentVo.setCreateDate(DateFormatUtil.format(new Date(comment.getCreated())));

                commentVoList.add(commentVo);

            }
        }
        pageBeanVo.setItems(commentVoList);
        return pageBeanVo;
    }

    //保存视频评论
    public void saveVideoComment(String videoId,String commentContent) {
        Long userId = UserHolder.get().getId();
        //准备评论对象
        Comment comment = new Comment();
        comment.setCommentType(5);
        comment.setUserId(userId);
        comment.setContent(commentContent);

        comment.setPublishId(new ObjectId(videoId));//视频ID
        Integer count=commentService.saveVideoComment(comment);
    }

    //给视频的评论点赞
    public void videoCommentLike(String commentId) {
        //1、被点赞评论的id
        ObjectId publishId = new ObjectId(commentId);
        //2\获得登录用户ID
        Long userId = UserHolder.get().getId();

        //组装评论点赞对象
        Comment comment = new Comment();
        comment.setCommentType(6);
        comment.setPublishId(publishId);
        comment.setUserId(userId);
        //3、调用方法操作数据库
        commentService.saveVideoCommentLike(publishId,userId);

        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE,userId,commentId),"1");
    }

    //视频的评论点赞取消
    public void videoCommentDislike(String commentId) {
        //1、被点赞评论的id
        ObjectId publishId = new ObjectId(commentId);
        //2\获得登录用户ID
        Long userId = UserHolder.get().getId();
        //3、调用方法操作数据库
        commentService.deleteVideoCommentLike(publishId,userId);
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_COMMENT_LIKE,userId,commentId));
    }



    /*//小视频点赞
    public void likeVideo(String videoId) {
        //1. 组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//视频id
        comment.setCommentType(1);//点赞
        comment.setUserId(UserHolder.get().getId());//操作人id

        //2. 调用service完成点赞
        commentService.saveVideoComment(comment);

        //3. 向redis中记录点赞操作
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.get().getId(), videoId), "1");

        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_LIKE);
    }

    //小视频取消点赞
    public void dislikeVideo(String videoId) {
        //1. 组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//视频id
        comment.setCommentType(1);//点赞
        comment.setUserId(UserHolder.get().getId());//操作人id

        //2. 调用service完成取消点赞
        commentService.deleteVideoComment(comment);

        //3. 向redis中删除点赞操作
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.get().getId(), videoId));

        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_DISLIKE);
    }

    //保存视频评论
    public void saveVideoComment(String videoId, String textComment) {
        //1. 组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//动态id
        comment.setCommentType(2);//评论
        comment.setUserId(UserHolder.get().getId());//操作人
        comment.setContent(textComment);//评论内容

        //2. 调用service保存评论
        commentService.saveVideoComment(comment);

        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_COMMENT);
    }

    //视频评论列表
    public PageBeanVo findVideoCommentList(String videoId, Integer pageNum, Integer pageSize) {
        //1. 调用service查询列表
        PageBeanVo pageBeanVo = commentService.findCommentByVideoId(videoId, pageNum, pageSize);

        //2. 组装返回结果
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        List<CommentVo> commentVoList = new ArrayList<>();//临时集合

        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {

                //3-1 设置评论信息
                CommentVo commentVo = new CommentVo();
                commentVo.setId(comment.getId().toHexString());//评论id
                commentVo.setContent(comment.getContent());//评论内容
                commentVo.setCreateDate(DateFormatUtil.format(new Date(comment.getCreated())));//评论的发布时间

                //3-2 设置评论发布人的信息
                Long userId = comment.getUserId();//评论人id
                UserInfo userInfo = userInfoService.findByUserId(userId);//评论人信息
                commentVo.setAvatar(userInfo.getAvatar());//评论人头像
                commentVo.setNickname(userInfo.getNickname());//评论人昵称

                //3-3 存储到临时集合
                commentVoList.add(commentVo);
            }
        }
        pageBeanVo.setItems(commentVoList);

        return pageBeanVo;
    }*/
}
